﻿using System;
using System.Linq;
using System.ComponentModel;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using Foundation;
using ICSharpCode.AvalonEdit.Document;

namespace Poet.ViewModels
{
    [DataContract]
    internal class RegexBuilderViewModel : ViewModel
    {
        public RegexBuilderViewModel()
        {
            Initialize();
        }

        private void PropertyChangedEventHandler(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            if (Regex != null)
                Matches = Regex.Matches(Document.Text).Cast<Match>().ToArray();
        }

        public TextDocument Document { get; set; }

        public TextDocument Pattern
        {
            get { return Get(() => Pattern); }
            set { Set(() => Pattern, value); }
        }

        public Match[] Matches
        {
            get { return Get(() => Matches); }
            set { Set(() => Matches, value); }
        }

        private string CurrentError { get; set; }

        private Regex Regex
        {
            get { return Get(() => Regex); }
            set { Set(() => Regex, value); }
        }

        protected override string GetDataErrorInfo(string propertyName = null)
        {
            if (propertyName == null) return CurrentError;

            if (propertyName == GetPropertyName(() => Pattern))
            {
                try
                {
                    Regex = new Regex(Pattern.Text);
                    CurrentError = null;
                }
                catch (Exception exception)
                {
                    Matches = null;
                    CurrentError = exception.Message;
                    return exception.Message;
                }
            }

            return null;
        }

        [OnDeserialized]
        private void Initialize(StreamingContext context = default(StreamingContext))
        {
            Pattern = new TextDocument();
            Document = new TextDocument();
            Pattern.TextChanged += (sender, args) => GetDataErrorInfo(GetPropertyName(() => Pattern));
            this[() => Regex].PropertyChanged += PropertyChangedEventHandler;
            Document.Changed += (sender, args) => PropertyChangedEventHandler(sender, null);
            ApplicationClosing += () => this.TrySerializeDataContract();
        }
    }
}
